home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1999 July: Mac OS SDK / Dev.CD Jul 99 SDK1.toast / Development Kits / Mac OS / QuickDraw3D 1.6 SDK / Mac SampleCode Previous / Geometry Samples- Mac / TriGrids / Sources / TriGridShell.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-05-18  |  18.0 KB  |  702 lines  |  [TEXT/MPS ]

  1. //
  2. // This is box, the QuickDraw 3D starter program.  Written for the
  3. // Getting started with QuickDraw 3D Develop article.  This app does not have 
  4. // graceful error handling - it's purpose is to illustrate a very basic QuickDraw 
  5. // 3D program.
  6. //
  7. // Nick Thompson - January 6th 1994
  8. //
  9. // Modification History:
  10. //
  11. //    1/6/95        nick    initial version based on cube
  12. //    12/31/94    nick    cube modifications for QuickDraw 3d sample code
  13. //    03/22/95    rdd        adapted from BoxShell.c: added simple picking
  14. //                        and trigrid selection via number keys
  15. //    04/12/95    rdd        added SetCameraLocation.
  16. //    04/14/95    rdd     added menu support.
  17. //  
  18.  
  19.  
  20. // system headers
  21. #include <Dialogs.h>
  22. #include <Devices.h>
  23. #include <DiskInit.h>
  24. #include <Fonts.h>
  25. #include <Menus.h>
  26. #include <QDOffScreen.h>
  27. #include <QuickDraw.h>
  28. #include <Resources.h>
  29. #include <SegLoad.h>
  30. #include <StandardFile.h>
  31. #include <TextEdit.h>
  32. #include <ToolUtils.h>
  33.  
  34. // for QuickDraw 3D
  35. #include "QD3D.h"
  36. #include "QD3DMath.h"
  37. #include "QD3DCamera.h"
  38. #include "QD3DDrawContext.h"
  39. #include "QD3DShader.h"
  40. #include "QD3DTransform.h"
  41. #include "QD3DGroup.h"
  42. #include "QD3DPick.h"
  43.  
  44.  
  45. #include "TriGridShell.h"
  46. #include "TriGrid3DSupport.h"
  47. #include "GeometrySample.h"
  48. #include "Textures2.h"
  49.  
  50. //-------------------------------------------------------------------------------------------
  51.  
  52. struct _documentRecord {
  53.     TQ3ViewObject    fView ;                    // the view for the scene
  54.     TQ3GroupObject    fModel ;                // object in the scene being modelled
  55.     TQ3StyleObject    fInterpolation ;        // interpolation style used when rendering
  56.     TQ3StyleObject    fBackFacing ;            // whether to draw shapes that face away from the camera
  57.     TQ3StyleObject    fFillStyle ;            // whether drawn as solid filled object or decomposed to components
  58.     TQ3Matrix4x4    fRotation ;                // the transform for the model
  59.     unsigned short    fGeometryNum ;            // triGrid geometry 1-9 (menu item number)
  60.     unsigned short    fTextureType ;            // method of uv parameterization for texture (menu item number)
  61.     unsigned short    fPictureNum ;            // PICT (menu item number)
  62. };
  63.  
  64. typedef struct _documentRecord DocumentRec, *DocumentPtr, **DocumentHdl ;
  65.  
  66.  
  67. //-------------------------------------------------------------------------------------------
  68. // function prototypes
  69.  
  70. static void         InitToolbox( void ) ;
  71. static Boolean        SetUpMenus (void) ;
  72. static void            IntializeMenuItems (DocumentPtr theDocument) ;
  73. static void         MainEventLoop( void ) ;
  74. static void         HandleKeyPress(EventRecord *pEvent) ;
  75. static void            DoAboutBox (void);
  76. static void            DoMenuCommand (long menuResult) ;
  77. static void         HandleOSEvent(EventRecord *event) ;
  78. static void            InitDocumentData( DocumentPtr theDocument ) ;
  79. static TQ3Status    DocumentDraw3DData( DocumentPtr theDocument ) ;
  80. static void            DisposeDocumentData( DocumentPtr theDocument) ;
  81. static void            SetCameraLocation (TQ3ViewObject view, float x, float y, float z);
  82. static void            ChangeGeometry (DocumentPtr theDocument) ;
  83. static void            DoPicking(EventRecord *event) ;
  84.  
  85.  
  86. //-------------------------------------------------------------------------------------------
  87. //
  88.  
  89. Boolean         gQuitFlag         = false ;
  90. WindowPtr        gMainWindow        = nil ;
  91. DocumentRec        gDocument ;
  92. Handle            ghMenuBar ;
  93. short            gNumPictures ;
  94.  
  95.  
  96. //-------------------------------------------------------------------------------------------
  97. // main()
  98. // entry point for the application, initialize the toolbox, initialize QuickDraw 3D
  99. // and enter the main event loop.  On exit from the main event loop, we want to call
  100. // the QuickDraw 3D exit function to clean up QuickDraw 3d.
  101.  
  102. void main(void)
  103. {
  104.     TQ3Status    myStatus;
  105.  
  106.     InitToolbox() ;
  107.     SetUpMenus () ;
  108.  
  109.     //    Initialize QuickDraw 3D, open a connection to the QuickDraw 3D library
  110.     myStatus = Q3Initialize();
  111.     if ( myStatus == kQ3Failure )
  112.         DebugStr("\pErInitialize returned failure.");            
  113.  
  114.     // set up our globals
  115.     gQuitFlag = false ;
  116.     gMainWindow = GetNewCWindow(kWindowRsrcID, nil, (WindowPtr)-1);
  117.  
  118.     InitDocumentData( &gDocument ) ;
  119.     IntializeMenuItems ( &gDocument ) ;
  120.  
  121.     MainEventLoop();
  122.     
  123.     DisposeDocumentData( &gDocument ) ;
  124.     
  125.     //    Close our connection to the QuickDraw 3D library
  126.     myStatus = Q3Exit();
  127.     if ( myStatus == kQ3Failure )
  128.         DebugStr("\pErExit returned failure.");
  129.     
  130. }
  131.  
  132. //-------------------------------------------------------------------------------------------
  133. //
  134.  
  135. void InitDocumentData( DocumentPtr theDocument ) 
  136. {
  137.     // sets up the 3d data for the scene
  138.     // Create view for QuickDraw 3D.
  139.     theDocument->fView = MyNewView( (WindowPtr)gMainWindow ) ;
  140.  
  141.     // the drawing styles:
  142.     theDocument->fInterpolation = Q3InterpolationStyle_New(kQ3InterpolationStyleNone) ;
  143.     theDocument->fBackFacing = Q3BackfacingStyle_New(kQ3BackfacingStyleBoth ) ;
  144.     theDocument->fFillStyle = Q3FillStyle_New(kQ3FillStyleFilled ) ;
  145.  
  146.     // set the rotation matrix the identity matrix
  147.     Q3Matrix4x4_SetIdentity(&theDocument->fRotation);        
  148.  
  149.     theDocument->fGeometryNum = iFlat ;
  150.     theDocument->fTextureType = iNoTexture ;
  151.     theDocument->fPictureNum  = iPictureFirst ;
  152.  
  153.     // the main display group:
  154.     theDocument->fModel = MyNewModel() ;
  155.     ChangeGeometry (theDocument);
  156. }
  157.  
  158. void DisposeDocumentData( DocumentPtr theDocument)
  159. {
  160.  
  161.     if(theDocument->fView)
  162.         Q3Object_Dispose(theDocument->fView) ;                // the view for the scene
  163.  
  164.     if(theDocument->fModel)
  165.         Q3Object_Dispose(theDocument->fModel) ;                // object in the scene being modelled
  166.  
  167.     if(theDocument->fInterpolation)
  168.         Q3Object_Dispose(theDocument->fInterpolation) ;        // interpolation style used when rendering
  169.  
  170.     if(theDocument->fBackFacing)
  171.         Q3Object_Dispose(theDocument->fBackFacing) ;        // whether to draw shapes that face away from the camera
  172.  
  173.     if(theDocument->fFillStyle)
  174.         Q3Object_Dispose(theDocument->fFillStyle) ;            // whether drawn as solid filled object or decomposed to components
  175.  
  176. }
  177. //-----------------------------------------------------------------------------
  178. // 
  179.  
  180. TQ3Status DocumentDraw3DData( DocumentPtr theDocument )
  181. {    
  182.     Q3View_StartRendering(theDocument->fView );
  183.     do {
  184.         Q3Style_Submit( theDocument->fInterpolation, theDocument->fView );
  185.         Q3Style_Submit( theDocument->fBackFacing, theDocument->fView );
  186.         Q3Style_Submit( theDocument->fFillStyle, theDocument->fView );
  187.         Q3MatrixTransform_Submit( &theDocument->fRotation, theDocument->fView );
  188.         Q3DisplayGroup_Submit( theDocument->fModel, theDocument->fView );
  189.     } while (Q3View_EndRendering(theDocument->fView) == kQ3ViewStatusRetraverse );
  190.     return kQ3Success ;
  191. }
  192.  
  193.  
  194. //----------------------------------------------------------------------------------
  195. //
  196. void InitToolbox()
  197. {
  198.     Handle        menuBar = nil;
  199.  
  200.     MaxApplZone() ;
  201.     MoreMasters() ; MoreMasters() ; MoreMasters() ; 
  202.     
  203.     InitGraf( &qd.thePort );
  204.     InitFonts();
  205.     InitWindows();
  206.     InitCursor();
  207.  
  208.     FlushEvents( everyEvent, 0 ) ;
  209.     // initialize application globals
  210.     
  211.     gQuitFlag = false;
  212.     
  213. }
  214.  
  215.  
  216. //-------------------------------------------------------------------------------------------
  217. //
  218. Boolean SetUpMenus (void)
  219. {
  220.     Boolean        goodMenus;
  221.  
  222.     goodMenus = true;
  223.  
  224.     ghMenuBar = GetNewMBar (kMenuBarRsrc);
  225.     if (ghMenuBar != nil)
  226.     {
  227.         SetMenuBar (ghMenuBar);
  228.         AppendResMenu (GetMenuHandle (mApple), (ResType) 'DRVR');
  229.         DrawMenuBar ();
  230.     }
  231.     else
  232.     {
  233.         DebugStr ("\pSetUpMenus: Couldn't find menu bar.");
  234.         ghMenuBar = nil;
  235.         goodMenus = false;
  236.     }
  237.  
  238.      return (goodMenus);
  239. }
  240.  
  241.  
  242. //-------------------------------------------------------------------------------------------
  243. //
  244. void IntializeMenuItems (DocumentPtr theDocument)
  245. {
  246.     MenuHandle    hMenu;
  247.     Str255        menuPrefix = {"\pPicture "},
  248.                 itemText,
  249.                 numString;
  250.     long        item;
  251.     short        rsrcID;
  252.     ResType        rsrcType;
  253.     Handle        hPict;
  254.  
  255.     hMenu = GetMenuHandle(mTexture);
  256.  
  257.     gNumPictures = Count1Resources ('PICT');
  258.  
  259.     /* PICT resources to be used as textures must be numbered starting with kFirstPICTRsrcID */
  260.     SetResLoad (false);
  261.     for (item = 0; item < gNumPictures; item++)
  262.     {
  263.         itemText[0] = 0;
  264.  
  265.         hPict = GetResource ('PICT', kFirstPICTRsrcID + item);
  266.         if (hPict != NULL)
  267.             GetResInfo (hPict, &rsrcID, &rsrcType, itemText);
  268.         else
  269.             break;
  270.  
  271.         if (itemText[0] == 0)
  272.         {
  273.             BlockMove ((Ptr) menuPrefix, (Ptr) itemText, (Size) menuPrefix[0]+1);
  274.             NumToString (item+1, numString);
  275.             itemText[0] += numString[0];
  276.             BlockMove ((Ptr) &numString[1], (Ptr) itemText[itemText[0]+1], (Size) numString[0]);
  277.         }
  278.  
  279.         AppendMenu (hMenu, itemText);
  280.     }
  281.     SetResLoad (true);
  282.  
  283.     gNumPictures = item;
  284.  
  285.     if (theDocument->fTextureType == iNoTexture)
  286.     {
  287.         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  288.             DisableItem(hMenu, item);
  289.     }
  290.  
  291.  
  292.     CheckItem (GetMenuHandle (mGeometry), theDocument->fGeometryNum, true);
  293.     CheckItem (hMenu, theDocument->fTextureType, true);
  294.     CheckItem (hMenu, theDocument->fPictureNum,  true);
  295. }
  296.  
  297.  
  298. //-------------------------------------------------------------------------------------------
  299. //
  300. void MainEventLoop()
  301. {
  302.     EventRecord     event;
  303.     WindowPtr       window;
  304.     short           thePart;
  305.     Rect            screenRect, updateRect;
  306.     Point            aPoint = {100, 100};
  307.     
  308.  
  309.     while( !gQuitFlag )
  310.     {
  311.         if (WaitNextEvent( everyEvent, &event, 0, nil ))
  312.         {
  313.  
  314.             switch (event.what) {
  315.                 case mouseDown:
  316.                 
  317.                     thePart = FindWindow( event.where, &window );
  318.                     
  319.                     switch( thePart ) {
  320.                         case inMenuBar: 
  321.                             DoMenuCommand (MenuSelect (event.where));
  322.                             break;
  323.  
  324.                         case inSysWindow:
  325.                             SystemClick (&event, window);
  326.                             break;
  327.  
  328.                         case inDrag:
  329.                             screenRect = (**GetGrayRgn()).rgnBBox;
  330.                             DragWindow( window, event.where, &screenRect );
  331.                             break ;
  332.                     
  333.                         case inContent:
  334.                             if (window != FrontWindow())
  335.                                 SelectWindow( window );
  336.                                 DoPicking(&event);
  337.                             break ;
  338.                     
  339.                         case inGoAway:
  340.                             if (TrackGoAway( window, event.where )) {
  341.                                 DisposeWindow ( window );
  342.                                 gQuitFlag = true;
  343.                             }
  344.                             break ;
  345.                             
  346.                         default:
  347.                         case inGrow:
  348.                         case inZoomIn:
  349.                         case inZoomOut:
  350.                             break ;
  351.                     }
  352.                     break ;
  353.                             
  354.                         
  355.                 case updateEvt:
  356.                     window = (WindowPtr)event.message;
  357.                     updateRect = (**(window->visRgn)).rgnBBox;
  358.                     SetPort( window ) ;
  359.                     BeginUpdate( window );
  360.                     DocumentDraw3DData( &gDocument ) ;
  361.                     EndUpdate( window );
  362.                     break ;
  363.                     
  364.                 case keyDown:
  365.                 case autoKey:
  366.                     HandleKeyPress(&event);
  367.                     break;
  368.                     
  369.                 case diskEvt:
  370.                     if ( HiWord(event.message) != noErr ) 
  371.                         (void) DIBadMount(aPoint, event.message);
  372.                     break;
  373.                     
  374.                 case osEvt:
  375.                 case activateEvt:
  376.                     break;
  377.  
  378.  
  379.             }
  380.         }
  381.         else {
  382.             // we received a null event, rotate the cube
  383.             TQ3Matrix4x4    tmp;
  384.             Rect            theRect = ((GrafPtr)gMainWindow)->portRect ;
  385.             
  386.             SetPort((GrafPtr)gMainWindow) ;
  387.             Q3Matrix4x4_SetRotate_XYZ(&tmp, 0.1, 0.12, 0.08);
  388.             Q3Matrix4x4_Multiply(&gDocument.fRotation, &tmp, &gDocument.fRotation);
  389.  
  390.             InvalRect( &theRect ) ;
  391.         }
  392.     }
  393. }
  394.  
  395.  
  396. //-------------------------------------------------------------------------------------------
  397. //
  398. void HandleKeyPress(EventRecord *pEvent)
  399. {
  400.     char            charCode;
  401.  
  402.     charCode = pEvent->message & charCodeMask;
  403.  
  404.     if (pEvent->modifiers & btnState)
  405.     {
  406.         /* Button is UP with a key */
  407.         if (pEvent->modifiers & cmdKey)
  408.         {
  409.             DoMenuCommand (MenuKey (charCode));
  410.         }
  411.     }
  412.     else
  413.     {
  414.         /* Button is DOWN with a key */
  415.     }
  416. }
  417.  
  418.  
  419. //-------------------------------------------------------------------------------------------
  420. //
  421. void DoAboutBox (void)
  422. {
  423.     DialogPtr    theDialog;
  424.     short        itemHit;
  425.  
  426.     theDialog = GetNewDialog(kDialogRsrcID, nil, (WindowPtr)-1);
  427.     if (theDialog == nil)
  428.         return;
  429.         
  430.     do
  431.     {
  432.         ModalDialog (nil, &itemHit);
  433.     }
  434.     while (itemHit != ok);
  435.  
  436.     DisposeDialog (theDialog);
  437. }
  438.  
  439.  
  440. //-------------------------------------------------------------------------------------------
  441. //
  442. void DoMenuCommand (long menuResult)
  443. {
  444.     short        menuID,
  445.                 itemNumber;
  446.  
  447.     if (! menuResult)
  448.         return;
  449.  
  450.     menuID       = HiWord (menuResult);
  451.     itemNumber = LoWord (menuResult);
  452.  
  453.     switch (menuID)
  454.     {
  455.         case mApple:
  456.             switch (itemNumber)
  457.             {
  458.             case iAbout:
  459.                 DoAboutBox();
  460.             break;
  461.  
  462.             default:
  463.                 {
  464.                     MenuHandle    hMenu;
  465.                     Str255        deskAccName;
  466.                     GrafPtr        oldPort;
  467.  
  468.                     hMenu = GetMenuHandle (menuID);
  469.                     if (hMenu != nil)
  470.                     {
  471.                         GetPort (&oldPort);
  472.  
  473.                         GetMenuItemText (hMenu, itemNumber, deskAccName);
  474.                         (void) OpenDeskAcc (deskAccName);
  475.                         SetPort (oldPort);
  476.                     }
  477.                 }
  478.                 break;
  479.             }
  480.             break;
  481.  
  482.         case mFile:
  483.             switch (itemNumber)
  484.             {
  485.             case iNew:            break;
  486.             case iOpen:            break;
  487.             case iClose:        break;
  488.  
  489.             case iQuit:
  490.                 gQuitFlag = true;break;
  491.  
  492.             default: SysBeep(1);break;
  493.             }
  494.             break;
  495.  
  496.         case mEdit:
  497.             if (! SystemEdit (itemNumber - 1))
  498.                 switch (itemNumber)
  499.                 {
  500.                 case iUndo:        break;
  501.                 case iCut:        break;
  502.                 case iCopy:        break;
  503.                 case iPaste:    break;
  504.                 case iClear:    break;
  505.                 }
  506.             break;
  507.  
  508.         case mGeometry:
  509.             if (itemNumber != gDocument.fGeometryNum)
  510.             {
  511.                 CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, false);
  512.                 gDocument.fGeometryNum = itemNumber;
  513.                 CheckItem (GetMenuHandle (mGeometry), gDocument.fGeometryNum, true);
  514.                 ChangeGeometry (&gDocument);
  515.             }
  516.             break;
  517.  
  518.         case mTexture:
  519.             if (itemNumber >= iNoTexture  &&  itemNumber <= iFaceTexture)
  520.             {
  521.                 if (itemNumber != gDocument.fTextureType)
  522.                 {
  523.                     long    item;
  524.  
  525.                     if (gDocument.fTextureType == iNoTexture)
  526.                     {
  527.                         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  528.                             EnableItem(GetMenuHandle (menuID), item);
  529.                     }
  530.                     else
  531.                     if (itemNumber == iNoTexture)
  532.                     {
  533.                         for (item = iPictureFirst; item < iPictureFirst + gNumPictures; item++)
  534.                             DisableItem(GetMenuHandle (menuID), item);
  535.                     }
  536.  
  537.                     CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, false);
  538.                     gDocument.fTextureType = itemNumber;
  539.                     CheckItem (GetMenuHandle (mTexture), gDocument.fTextureType, true);
  540.                     ChangeGeometry (&gDocument);
  541.                 }
  542.             }
  543.             else
  544.             if (itemNumber >= iPictureFirst  && itemNumber <= iPictureFirst + gNumPictures - 1)
  545.             {
  546.                 if (itemNumber != gDocument.fPictureNum)
  547.                 {
  548.                     CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, false);
  549.                     gDocument.fPictureNum = itemNumber;
  550.                     CheckItem (GetMenuHandle (mTexture), gDocument.fPictureNum, true);
  551.                     ChangeGeometry (&gDocument);
  552.                 }
  553.             }
  554.             break;
  555.  
  556.         default:
  557.             break;
  558.  
  559.     }  /*  switch (menuID)  */
  560.  
  561.     HiliteMenu (0);
  562. }
  563.  
  564.  
  565. //-------------------------------------------------------------------------------------------
  566. //
  567. void SetCameraLocation (TQ3ViewObject view, float x, float y, float z)
  568. {
  569.     TQ3CameraObject    camera;
  570.     TQ3CameraData    cameraData;
  571.  
  572.     Q3View_GetCamera(view, &camera);
  573.     if (camera != nil)
  574.     {
  575.         Q3Camera_GetData(camera, &cameraData);
  576.         Q3Point3D_Set(&cameraData.placement.cameraLocation, x, y, z);
  577.         Q3Camera_SetData(camera, &cameraData);
  578.         Q3Object_Dispose(camera);
  579.     }
  580. }
  581.  
  582.  
  583. //-------------------------------------------------------------------------------------------
  584. //
  585. void ChangeGeometry (DocumentPtr theDocument)
  586. {
  587.     TQ3Status            status;
  588.     TQ3Object            object;
  589.     TQ3GroupPosition    position;
  590.     unsigned long        triGridLibNum;
  591.  
  592.     if (theDocument->fModel == nil)
  593.         return;
  594.  
  595.     status = Q3Group_GetFirstPositionOfType(theDocument->fModel, kQ3ShapeTypeGeometry, &position);
  596.     if (status == kQ3Success  &&  position != nil)
  597.     {
  598.         object = Q3Group_RemovePosition(theDocument->fModel, position);
  599.         Q3Object_Dispose(object);
  600.         object = NULL;
  601.     }
  602.  
  603.     switch (theDocument->fTextureType)
  604.     {
  605.         case iNoTexture:        triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_Simple;            break;
  606.         case iGeometryTexture:    triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVGeoAttributes;    break;
  607.         case iFaceTexture:        triGridLibNum = (theDocument->fGeometryNum-1) + kGeometryLibraryRange_UVFaceAttributes;break;
  608.     }
  609.     object = NewLibraryTriGrid(triGridLibNum);
  610.     if (object == NULL)
  611.         return;
  612.     Q3Group_AddObject (theDocument->fModel, object);
  613.  
  614.     /* Add diffuse color if no texture */
  615.     if (theDocument->fTextureType == iNoTexture)
  616.     {
  617.         TQ3AttributeSet        attrSet;
  618.         TQ3ColorRGB            rgbColor;
  619.  
  620.         attrSet = Q3AttributeSet_New();
  621.         if (attrSet != NULL)
  622.         {
  623.             Q3ColorRGB_Set(&rgbColor, 0.0, 0.75, 0.75);
  624.             status = Q3AttributeSet_Add(attrSet, kQ3AttributeTypeDiffuseColor, &rgbColor);
  625.             if (status == kQ3Success)
  626.             {
  627.                 Q3Geometry_SetAttributeSet(object, attrSet);
  628.                 Q3Object_Dispose(attrSet);
  629.             }
  630.         }
  631.     }
  632.     else
  633.         /* Add texture shader */
  634.         AddResourceTextureToGroup(theDocument->fPictureNum - iPictureFirst + kFirstPICTRsrcID, theDocument->fModel);
  635.  
  636.     Q3Object_Dispose(object);
  637.  
  638.     /* (These cameral locations could be calculated) */
  639.     switch (theDocument->fGeometryNum)
  640.     {
  641.     case iFlat:            SetCameraLocation (theDocument->fView, 0.0, 0.0,  4.0);    break;
  642.     case iTorus:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  643.     case iWaveyTorus:    SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  644.     case iSplash:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 25.0);    break;
  645.     case iSphere:        SetCameraLocation (theDocument->fView, 0.0, 0.0,  7.0);    break;
  646.     case iCone:            SetCameraLocation (theDocument->fView, 0.0, 0.0,  9.0);    break;
  647.     case iPipe:            SetCameraLocation (theDocument->fView, 0.0, 0.0, 10.0);    break;
  648.     case iSteps:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 30.0);    break;
  649.     case iSpring:        SetCameraLocation (theDocument->fView, 0.0, 0.0, 11.0);    break;
  650.     }
  651. }
  652.  
  653.  
  654. //-------------------------------------------------------------------------------------------
  655. //
  656. void DoPicking(EventRecord *event)
  657. {
  658.     Point                    screenPoint;
  659.     TQ3WindowPointPickData    withData;
  660.     unsigned long            numPicked;
  661.     TQ3PickObject            pickObject;
  662.     TQ3Status                status;
  663.     TQ3ViewStatus            viewStatus;
  664.     
  665.     withData.data.sort             =    kQ3PickSortNone;
  666.     withData.data.numHitsToReturn=    kQ3ReturnAllHits;
  667.     withData.data.mask             =    kQ3PickDetailMaskObject;
  668.                                   
  669.     screenPoint = event->where;
  670.     GlobalToLocal (&screenPoint);
  671.     withData.point.x = screenPoint.h;
  672.     withData.point.y = screenPoint.v;
  673.  
  674.     withData.vertexTolerance = withData.edgeTolerance = 2.0;
  675.  
  676.     pickObject = Q3WindowPointPick_New(&withData);
  677.  
  678.     status = Q3View_StartPicking(gDocument.fView, pickObject);
  679.     if (status == kQ3Failure)
  680.         debugstr ("DoPicking: Q3View_StartPicking failed.");
  681.     do {
  682.         status = Q3DisplayGroup_Submit(gDocument.fModel, gDocument.fView);
  683.         if (status == kQ3Failure)
  684.             debugstr ("DoPicking: Q3View_StartPicking failed.");
  685.  
  686.         viewStatus = Q3View_EndPicking(gDocument.fView);
  687.     } while (viewStatus == kQ3ViewStatusRetraverse);
  688.  
  689.     if (viewStatus != kQ3ViewStatusDone)
  690.         debugstr ("DoPicking: Q3View_EndPicking failed.");
  691.  
  692.  
  693.     if (Q3Pick_GetNumHits(pickObject, &numPicked) && (numPicked != 0)) {
  694.         SetCursor(*GetCursor(plusCursor));
  695.         SysBeep(1);
  696.     } else {
  697.         SetCursor(&qd.arrow);
  698.     }
  699.  
  700.     Q3Object_Dispose(pickObject);
  701. }
  702.